package logic;

import java.util.TreeSet;

import data.RatingTuple;
import data.SystemData;
import data.UserTuple;
import exceptions.MissingMandantoryFieldException;
import exceptions.ObjectAlreadyInitializedException;
import exceptions.UserAlreadyExistException;
import exceptions.UserDoesNotExistsException;
import exceptions.WrongPasswordException;
import guiDisplay.MovieData;


/**
 * describes the system's Facade, which delegates GUI requests
 * the Facade is a singleton
 *
 */

public class Facade {
	private static Facade _facade;

	private SystemHandler _sysHandler;
	private AdminHandler _adHandler;
	private UserHandler _usrHandler;
	private RatingHandler _ratingHandler;
	private AlgoHandler _algoHandler;

	private Facade(SystemHandler systemHandler, AdminHandler adminHandler, UserHandler userHandler, AlgoHandler algoHandler, RatingHandler ratingHandler){
		_sysHandler = systemHandler;
		_adHandler = adminHandler;
		_usrHandler = userHandler;
		_algoHandler= algoHandler;
		_ratingHandler=ratingHandler;
	}

	public static  Facade getInstance(){
		//TODO what to do here if facade is null?
		return _facade;
	}

	public static void init(SystemHandler s, AdminHandler a, UserHandler u, Algorithm algo) throws ObjectAlreadyInitializedException{
		if (_facade==null){
			_facade = new Facade(new SystemHandler(),new AdminHandler(), new UserHandler(),new AlgoHandler(algo),new RatingHandler ());
		}else{
			throw new ObjectAlreadyInitializedException("Facade already initialized");
		}
	}

	public boolean login(String userName, String password) {//throws UserDoesNotExistsException{
		return _usrHandler.login(userName, password);
	}

	public void logout(/*String userName*/) {//throws UserDoesNotExistsException{
		_usrHandler.logout(/*userName*/);
	}


	public UserTuple deleteUser(String userName,String adminName) throws UserDoesNotExistsException{
		return _adHandler.deleteUser(userName, adminName);
	}

	public boolean registerUser(String userName, String password1, String password2, String day,String month, String year, String sex) throws WrongPasswordException, MissingMandantoryFieldException, UserAlreadyExistException{
		_usrHandler.registerUser(userName,password1, password2, day,month,year, sex);
		return true;
	}

	public void changeDetails(String name, String oldpass, String pass1, String pass2,
			String day, String month, String year, boolean b) {
		_usrHandler.changeDetails(name, oldpass, pass1, pass2, day , month, year, b);


	}

	public boolean addMovie(String name, String category, String director, String lang ,String raters,String rating, String year,  String length, String picture) {//throws MovieAlreadyExistsException{
		return _adHandler.addMovie(name, category, director, lang, raters, rating, year, length , picture);
	}

	public boolean deleteMovie(String name){
		return _adHandler.deleteMovie(name);
	}

	public void addRating(String user , String movie, String rating , String description){
		_sysHandler.addRating(user,movie,rating,description);
	}

	public void changeRating(String user , String movie, String rating , String description){
		_sysHandler.changeRating(user,movie,rating,description);
	}

	public void getRecommendation(String user){
		_algoHandler.setRecommendation(user,0);
	}

	public MovieData getMovieData(String text) {
		return _sysHandler.getMovieData(text);

	}


	public String[] getMovies() {
		return _sysHandler.getMovies();
	}

	public Object[] getUsers(String user) {
		return _sysHandler.getUsers(user);
	}

	public void exit() {
		SystemData.getInstance().exit();
	}

	public void nextTenMovies(String user,int begin) {
		_algoHandler.setRecommendation(user,begin);

	}

	public void showRating(String movieName, String userName) {
		_usrHandler.hasSeenMovie(movieName, userName);
	}

	public void removeRating(String movieName, String userName) {
		_ratingHandler.removeRating(movieName,userName);

	}

	public int getNumRating(String user) {
		return _usrHandler.getNumRating(user);
	}

	public TreeSet<RatingTuple> getUserRatings(String user) {
		return _usrHandler.getUserRatings(user);
	}


	public String[] haveSeenRating(String user, String movie) {
		return _usrHandler.haveSeenRating(user, movie);
	}

	public String[] search(String src) {
		return SystemData.getInstance().search(src);
	}
}
